import dash
from dash import html
import feffery_antd_components as fac
import feffery_utils_components as fuc
import feffery_leaflet_components as flc
from dash.dependencies import Input, Output, State

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        # 页首布局，固定像素高度
        html.Div(
            [],
            style={
                'height': '64px',
                'boxShadow': '0px 0px 12px rgba(0, 0, 0, .12)',
                'background': 'white'
            }
        ),

        # 下方主内容区域relative容器，利用calc撑满剩余高度
        html.Div(
            [
                # 底层在线地图，绝对定位撑满父容器
                flc.LeafletMap(
                    [
                        # 添加瓦片底图
                        flc.LeafletTileLayer()
                    ],
                    zoomControl=False,  # 隐藏自带的放大缩小控件
                    style={
                        'position': 'absolute',
                        'width': '100%',
                        'height': '100%'
                    }
                ),

                # 风格一折叠按钮，对应左侧面板
                html.Span(
                    fac.AntdIcon(
                        id='left-panel-fold-icon',
                        icon='antd-menu-fold'
                    ),
                    id='left-panel-fold',
                    style={
                        'position': 'absolute',
                        'top': 15,
                        'left': 8,
                        'zIndex': 9999,
                        'cursor': 'pointer',
                        'fontSize': 18
                    }
                ),

                # 左侧悬浮面板，绝对定位，拉高zIndex
                html.Div(
                    [
                        fac.AntdResult(
                            status='info',
                            subTitle='左侧面板内容示例'
                        ),

                        # 受左侧面板折叠影响位置的悬浮工具条，利用绝对定位与左侧面板绑定
                        fac.AntdSpace(
                            [
                                fac.AntdButton(
                                    [
                                        fac.AntdIcon(
                                            icon='antd-zoom-in',
                                            style={
                                                'paddingRight': '5px'
                                            }
                                        ),
                                        '操作XX'
                                    ]
                                )
                            ] * 5,
                            size=0,
                            style={
                                'position': 'absolute',
                                'top': 0,
                                'left': 'calc(100% + 10px)'
                            }
                        )
                    ],
                    id='left-panel',
                    style={
                        'position': 'absolute',
                        'left': 0,
                        'top': 10,
                        'bottom': 10,
                        'width': 400,
                        'background': 'white',
                        'boxShadow': '0 2px 2px rgb(0 0 0 / 15%)',
                        'zIndex': 999,
                        'borderBottomRightRadius': '6px',
                        'borderTopRightRadius': '6px',
                        'transition': 'left 0.3s ease'
                    }
                ),

                # 右侧悬浮面板，绝对定位，拉高zIndex
                html.Div(
                    html.Div(
                        [
                            # 风格二折叠按钮，对应右侧面板
                            html.Span(
                                fac.AntdIcon(
                                    id='right-panel-fold-icon',
                                    icon='antd-menu-unfold'
                                ),
                                id='right-panel-fold',
                                style={
                                    'cursor': 'pointer',
                                    'fontSize': 18,
                                    'position': 'absolute',
                                    'top': 8,
                                    'left': 8
                                }
                            ),

                            fac.AntdResult(
                                status='info',
                                subTitle='右侧面板内容示例'
                            ),

                            # 受右侧面板折叠影响位置的悬浮工具条，利用绝对定位与右侧面板绑定
                            fac.AntdSpace(
                                [
                                    fac.AntdButton(
                                        [
                                            fac.AntdIcon(
                                                icon='antd-zoom-in',
                                                style={
                                                    'paddingRight': '5px'
                                                }
                                            ),
                                            '操作XX'
                                        ],
                                        style={
                                            'display': 'flex',
                                            'flexDirection': 'column',
                                            'height': 'auto',
                                            'alignItems': 'center',
                                            'padding': '3px 5px'
                                        }
                                    )
                                ] * 10,
                                size=0,
                                direction='vertical',
                                style={
                                    'position': 'absolute',
                                    'top': 25,
                                    'right': 'calc(100% + 10px)'
                                }
                            )
                        ],
                        style={
                            'position': 'relative',
                            'width': '100%',
                            'height': '100%'
                        }
                    ),
                    id='right-panel',
                    style={
                        'position': 'absolute',
                        'right': 0,
                        'top': 10,
                        'bottom': 10,
                        'width': 400,
                        'background': 'white',
                        'boxShadow': '0 2px 2px rgb(0 0 0 / 15%)',
                        'zIndex': 999,
                        'borderBottomLeftRadius': '6px',
                        'borderTopLeftRadius': '6px',
                        'transition': 'right 0.3s ease'
                    }
                )
            ],
            style={
                'height': 'calc(100vh - 64px)',
                'position': 'relative'
            }
        )
    ],
    style={
        'overflowX': 'hidden'
    }
)

# 左侧面板折叠回调，使用浏览器端回调提升交互顺畅性
app.clientside_callback(
    '''
    (n_clicks, oldStyle) => {
        if (n_clicks) {
            if (oldStyle?.left === 0) {
                return [
                    {
                        ...oldStyle,
                        left: -364
                    },
                    'antd-menu-unfold'
                ]
            }
            return [
                {
                    ...oldStyle,
                    left: 0
                },
                'antd-menu-fold'
            ]
        }
        return window.dash_clientside.no_update;
    }
    ''',
    [Output('left-panel', 'style'),
     Output('left-panel-fold-icon', 'icon')],
    Input('left-panel-fold', 'n_clicks'),
    State('left-panel', 'style')
)

# 右侧面板折叠回调，使用浏览器端回调提升交互顺畅性
app.clientside_callback(
    '''
    (n_clicks, oldStyle) => {
        if (n_clicks) {
            if (oldStyle?.right === 0) {
                return [
                    {
                        ...oldStyle,
                        right: -364
                    },
                    'antd-menu-fold'
                ]
            }
            return [
                {
                    ...oldStyle,
                    right: 0
                },
                'antd-menu-unfold'
            ]
        }
        return window.dash_clientside.no_update;
    }
    ''',
    [Output('right-panel', 'style'),
     Output('right-panel-fold-icon', 'icon')],
    Input('right-panel-fold', 'n_clicks'),
    State('right-panel', 'style')
)

if __name__ == '__main__':
    app.run(debug=True)
